import { ICaller } from "./ICaller";
import { ArrayUtil } from "../../utils/ArrayUtil";
// did
//class Caller
export class Caller implements ICaller {
  public addCall(key: number | string, handler: Function): void {
    var loc1 = this.getlistByType(key);
    loc1.push(handler);
  }

  public hasCallFun(key: number | string, handler: Function) {
    var loc1 = this.getlistByType(key);
    return loc1.indexOf(handler) >= 0;
  }

  public removeCall(key: number | string, handler: Function): void {
    if (this._callerIng.hasOwnProperty(key)) {
      this._removeLater.push(handler);
      return;
    }
    var handlers = this._callerMap[key];
    if (handlers && handlers.length > 0) {
      ArrayUtil.removeItem(handlers, handler);
    }
  }

  public call(arg1: number | string, ...rest: any[]) {
    var loc1 = this._callerMap[arg1];
    if (loc1 && loc1.length > 0) {
      this._callerIng[arg1] = arg1;
      for (let key of loc1) {
        key.apply(null, rest);
      }
      delete this._callerIng[arg1];
      while (this._removeLater.length > 0) {
        ArrayUtil.removeItem(loc1, this._removeLater.shift());
      }
    }
    return true;
  }

  public dispose(arg1 = true): void {
    for (let key in this._callerMap) {
      var loc1 = this._callerMap[key];
      loc1.length = 0;
      delete this._callerMap[key];
    }
  }

  private getlistByType(key: number | string) {
    if (key in this._callerMap) {
      return this._callerMap[key];
    }
    this._callerMap[key] = [];
    return this._callerMap[key];
  }

  public removeCallByType(key: number | string): void {
    var loc1 = this._callerMap[key];
    if (loc1) {
      loc1.length = 0;
      delete this._callerMap[key];
    }
  }

  public hasCall(key: number | string) {
    return key in this._callerMap;
  }

  private _callerMap: Record<number | string, Function[]> = {};

  private _callerIng: Record<number | string, number | string> = {};

  private _removeLater: Array<Function> = [];
}
